package com.vichat.workflow.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.vichat.workflow.entity.*;
import com.vichat.workflow.service.IWorkflowServcie;
import com.vichat.workflow.service.WorkflowConstant;
import com.vichat.workflow.vo.WfNodePropsVO;
import com.vichat.workflow.vo.WorkflowUser;
import com.vichat.common.cache.RedisHelper;
import com.vichat.common.util.*;
import com.vichat.common.vo.Grid;
import com.vichat.common.vo.Json;
import com.vichat.common.vo.PageFilter;
import com.vichat.res.entity.ResConfig;
import com.vichat.res.service.IResService;
import com.vichat.user.controller.BaseController;
import com.vichat.user.entity.SecRole;
import com.vichat.user.entity.UserBasic;
import com.vichat.user.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;

/**
 * Created by wangluyin on 2018/5/21.
 */
@Controller
@RequestMapping("/vcapi/wf/")
public class WorkflowController extends BaseController {

    protected static final Logger logger = LoggerFactory.getLogger(WorkflowController.class);
    @Autowired
    HttpServletRequest request;
    @Autowired
    HttpServletResponse response;
    @Autowired
    private IWorkflowServcie workflowServcie;
    @Autowired
    private IUserService userService;
    @Autowired
    private IResService resService;

    @RequestMapping("/getFlows")
    @ResponseBody
    public Grid getFlows() {
        Grid grid = new Grid();
        try {
            WorkflowUser workflowUser = toWorkflowUser(getSessionUser());
            List<Wf> wfs = workflowServcie.getWorkflows(workflowUser.getPartyId());
            grid.setRows(wfs);
        } catch (Exception e) {
            e.printStackTrace();
            grid.setErrorMsg(e.getMessage());
        }
        return grid;
    }

    @RequestMapping("/getFlowProps")
    @ResponseBody
    public Json getFlowProps(long insFlowId) {
        Json json = new Json();
        try {
            InsWf insWf = workflowServcie.getInsFlowById(insFlowId);
            List<WfNodeAttrFieldset> fieldsets = workflowServcie.getAttrFieldsetByNodeId(-1L, insWf.getFlowId());
            List<JSON> attrsJson = new ArrayList<>();
            for (WfNodeAttrFieldset fieldset : fieldsets) {
                List<WfNodeAttr> attrs = workflowServcie.getAttrsByFieldsetId(-1, fieldset.getFieldsetId());
                attrsJson.addAll(getAttrJsonWithValue(attrs, insFlowId, -1));
                fieldset.setAttrs(attrsJson);
            }

            json.setObj(attrsJson);
            json.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            json.setMsg(e.getMessage());
        }
        return json;
    }

    @RequestMapping("/getNodePropsByNodeId")
    @ResponseBody
    public Json getNodePropsByNodeId(long nodeId, long insFlowId, long insNodeId) {
        Json json = new Json();
        try {
            WfNodePropsVO nodeProps = new WfNodePropsVO();
            WfNode node = workflowServcie.getWfNodeByNodeId(nodeId);
            nodeProps.setWfNode(node);
            if (node == null) {
                throw new Exception("工作流节点数据异常");
            }
            Wf wf = workflowServcie.getWorkflowById(node.getFlowId());
            if (wf == null) {
                throw new Exception("工作流节点数据异常");
            }
            nodeProps.setWf(wf);

            boolean isDefault = false;
            try {
                if (StringUtils.isNotBlank(node.getNodeExp())) {
                    JSONObject nodeJson = JSON.parseObject(node.getNodeExp());
                    if (nodeJson.containsKey("isBack")) {
                        nodeProps.setIsBack(StringUtil.stringToBoolean(nodeJson.getString("isBack")));
                    }
                    if (nodeJson.containsKey("isPrint")) {
                        nodeProps.setIsPrint(StringUtil.stringToBoolean(nodeJson.getString("isPrint")));
                    }
                    if (nodeJson.containsKey("isDefault")) {
                        isDefault = StringUtil.stringToBoolean(nodeJson.getString("isDefault"));
                    }
                }
            } catch (Exception e) {
                //json格式转换问题
            }

            if (!isDefault) {

                List<WfNodeAttrFieldset> fieldsets = workflowServcie.getAttrFieldsetByNodeId(node.getNodeId(), node.getFlowId());
                for (WfNodeAttrFieldset fieldset : fieldsets) {
                    List<WfNodeAttr> attrs = workflowServcie.getAttrsByFieldsetId(node.getNodeId(), fieldset.getFieldsetId());
                    List<JSON> attrsJson = getAttrJsonWithValue(attrs, insFlowId, insNodeId);
                    fieldset.setAttrs(attrsJson);
                }
                nodeProps.setAttrFieldsets(fieldsets);
            } else {
                List<WfNodeAttrFieldset> fieldsets = workflowServcie.getAttrFieldsetByNodeId(-1L, node.getFlowId());
                for (WfNodeAttrFieldset fieldset : fieldsets) {
                    List<WfNodeAttr> attrs = workflowServcie.getAttrsByFieldsetId(-1, fieldset.getFieldsetId());
                    List<JSON> attrsJson = getAttrJsonWithValue(attrs, insFlowId, -1);
                    fieldset.setAttrs(attrsJson);
                }
                nodeProps.setAttrFieldsets(fieldsets);
            }


            json.setObj(nodeProps);
            json.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            json.setMsg(e.getMessage());
        }
        return json;
    }

    @RequestMapping("/getStartNodeProps")
    @ResponseBody
    public Json getStartNodeProps(String flowCode) {
        Json json = new Json();
        try {
            WfNodePropsVO nodeProps = new WfNodePropsVO();
            Wf wf = workflowServcie.getWorkflowByFlowCode(flowCode);
            if (wf == null) {
                throw new Exception("未找到工作流模板");
            }
            nodeProps.setWf(wf);
            WfNode node = workflowServcie.getWfStartNode(wf.getFlowId());
            if (node == null) {
                throw new Exception("工作流节点数据异常");
            }
            nodeProps.setWfNode(node);
            List<WfNodeAttrFieldset> fieldsets = workflowServcie.getAttrFieldsetByNodeId(node.getNodeId(), node.getFlowId());
            for (WfNodeAttrFieldset fieldset : fieldsets) {
                List<WfNodeAttr> attrs = workflowServcie.getAttrsByFieldsetId(node.getNodeId(), fieldset.getFieldsetId());
                List<JSON> attrsJson = getAttrJson(attrs);
                fieldset.setAttrs(attrsJson);
            }
            nodeProps.setAttrFieldsets(fieldsets);

            if (StringUtils.isNotBlank(node.getNodeExp())) {
                JSONObject nodeJson = JSON.parseObject(node.getNodeExp());
                if (nodeJson.containsKey("isBack")) {
                    nodeProps.setIsBack(StringUtil.stringToBoolean(nodeJson.getString("isBack")));
                }
                if (nodeJson.containsKey("isPrint")) {
                    nodeProps.setIsBack(StringUtil.stringToBoolean(nodeJson.getString("isPrint")));
                }
            }

            json.setObj(nodeProps);
            json.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            json.setMsg(e.getMessage());
        }
        return json;
    }

    protected List<JSON> getAttrJsonWithValue(List<WfNodeAttr> attrs, long insFlowId, long insNodeId) {
        List<JSON> list = new ArrayList<JSON>();

        for (WfNodeAttr attr : attrs) {
            JSONArray validates;
            JSONObject jsonAttrExp;
            JSONObject json = (JSONObject) JSON.toJSON(attr);

            String value = getAttrValue(insFlowId, insNodeId, attr.getAttrCode(), attr.getIsNodeAttr());

            if (StringUtils.isNotBlank(attr.getAttrExp())) {
                jsonAttrExp = JSON.parseObject(attr.getAttrExp());
            } else {
                jsonAttrExp = new JSONObject();
            }
            if (jsonAttrExp.containsKey("validate")) {
                validates = jsonAttrExp.getJSONArray("validate");
                JSONObject validate = (JSONObject) validates.get(0);
                validate.put("required", StringUtil.stringToBoolean(attr.getRequired()));
            } else {
                validates = new JSONArray();
                JSONObject validate = new JSONObject();
                validate.put("required", StringUtil.stringToBoolean(attr.getRequired()));
                validates.add(validate);
                jsonAttrExp.put("validate", validates);
            }
            json.putAll(jsonAttrExp);
            json.put("readonly", StringUtil.stringToBoolean(attr.getReadonly()));
            json.put("name", attr.getAttrCode());
            json.put("val", value);

            if (jsonAttrExp.containsKey("isResources")) {
                json.put("isResources", StringUtil.stringToBoolean(jsonAttrExp.getString("isResources")));
            }

            if ("gps".equals(attr.getAttrType())) {
                try {
                    if (value.indexOf("[") != -1 && value.indexOf("]") != -1) {
                        String gps = value.substring(value.indexOf("[") + 1, value.indexOf("]"));
                        json.put("gps", gps);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }


            json.remove("isNodeAttr");
            json.remove("attrExp");
            json.remove("required");
            json.remove("sort");

            list.add(json);
        }

        return list;
    }

    private String getAttrValue(long insFlowId, long insNodeId, String attrCode, String isNodeAttr) {
        String value = "";
        if ("N".equals(isNodeAttr)) {
            insNodeId = -1l;
        }
        InsWfNodeAttr attr = workflowServcie.getInsNodeAttr(insFlowId, insNodeId, attrCode);
        if (attr != null && !attr.getAttrValue().isEmpty()) {
            value = attr.getAttrValue();
        }
        return value;
    }

    protected List<JSON> getAttrJson(List<WfNodeAttr> attrs) {
        List<JSON> list = new ArrayList<JSON>();

        for (WfNodeAttr attr : attrs) {
            JSONObject json = (JSONObject) JSON.toJSON(attr);
            JSONArray validates;
            JSONObject jsonAttrExp;
            if (StringUtils.isNotBlank(attr.getAttrExp())) {
                jsonAttrExp = JSON.parseObject(attr.getAttrExp());
            } else {
                jsonAttrExp = new JSONObject();
            }
            // {"val": "","options": ["统一社会信用代码", "企业注册号","组织机构代码"],"validate": [{"message": "请选择案由","trigger": "change"}]}
            if (jsonAttrExp.containsKey("validate")) {
                validates = jsonAttrExp.getJSONArray("validate");
                JSONObject validate = (JSONObject) validates.get(0);
                validate.put("required", StringUtil.stringToBoolean(attr.getRequired()));
            } else {
                validates = new JSONArray();
                JSONObject validate = new JSONObject();
                validate.put("required", StringUtil.stringToBoolean(attr.getRequired()));
                validates.add(validate);
                jsonAttrExp.put("validate", validates);
            }
            json.putAll(jsonAttrExp);
            json.put("readonly", StringUtil.stringToBoolean(attr.getReadonly()));
            json.put("name", attr.getAttrCode());

            if (jsonAttrExp.containsKey("isResources")) {
                json.put("isResources", StringUtil.stringToBoolean(jsonAttrExp.getString("isResources")));
            }

            json.remove("isNodeAttr");
            json.remove("attrExp");
            json.remove("required");
            json.remove("sort");

            list.add(json);
        }
        return list;
    }


    @RequestMapping("/startFlow")
    @ResponseBody
    public Json startFlow(@RequestBody Map<String, Object> models) {
        Json json = new Json();

        try {
            if (!models.containsKey("flowId")) {
                throw new Exception("传入参数错误:flowId为空");
            }
            if (!models.containsKey("nodeId")) {
                throw new Exception("传入参数错误:nodeId为空");
            }

            int flowId = (Integer) models.get("flowId");
            int nodeId = (Integer) models.get("nodeId");

            if (NumberUtils.isNullOrZero(flowId)) {
                throw new Exception("传入参数错误:flowId为空");
            }
            if (NumberUtils.isNullOrZero(nodeId)) {
                throw new Exception("传入参数错误:nodeId为空");
            }

            Wf wf = workflowServcie.getWorkflowById(flowId);
            if (wf == null) {
                throw new Exception("未找到工作流模板");
            }

            WfNode node = workflowServcie.getWfStartNode(flowId);
            if (node == null) {
                throw new Exception("工作流节点数据异常");
            }
            WorkflowUser workflowUser = toWorkflowUser(getSessionUser());
            InsWf insWf = workflowServcie.startFlow(wf, node, models, workflowUser);

            json.setObj(insWf);
            json.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            json.setMsg(e.getMessage());
        }
        return json;
    }


    @RequestMapping("/commitFlow")
    @ResponseBody
    public Json commitFlow(@RequestBody Map<String, Object> models) {
        Json json = new Json();

        try {
            if (!models.containsKey("insNodeId")) {
                throw new Exception("传入参数错误:insNodeId为空");
            }

            int insNodeId = (Integer) models.get("insNodeId");

            if (NumberUtils.isNullOrZero(insNodeId)) {
                throw new Exception("传入参数错误:insNodeId为空");
            }

            WorkflowUser workflowUser = toWorkflowUser(getSessionUser());

            if (!userPermissionValidation(insNodeId, workflowUser)) {
                throw new Exception("权限不足");
            }

            InsWf insWf = workflowServcie.commitFlow(insNodeId, models, workflowUser);

            json.setObj(insWf);
            json.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            json.setMsg(e.getMessage());
        }
        return json;
    }

    @RequestMapping("/saveFlow")
    @ResponseBody
    public Json saveFlow(@RequestBody Map<String, Object> models) {
        Json json = new Json();

        try {

            if (!models.containsKey("insNodeId")) {
                throw new Exception("传入参数错误:insNodeId为空");
            }

            int insNodeId = (Integer) models.get("insNodeId");

            if (NumberUtils.isNullOrZero(insNodeId)) {
                throw new Exception("传入参数错误:insNodeId为空");
            }

            WorkflowUser workflowUser = toWorkflowUser(getSessionUser());

            if (!userPermissionValidation(insNodeId, workflowUser)) {
                throw new Exception("权限不足");
            }

            InsWf insWf = workflowServcie.saveFlow(insNodeId, models, workflowUser);

            json.setObj(insWf);
            json.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            json.setMsg(e.getMessage());
        }
        return json;
    }

    @RequestMapping("/backFlow")
    @ResponseBody
    public Json backFlow(long insNodeId, String replyNote) {
        Json json = new Json();

        try {
            if (NumberUtils.isNullOrZero(insNodeId)) {
                throw new Exception("传入参数错误:insNodeId为空");
            }

            if (!StringUtils.isNotBlank(replyNote)) {
                throw new Exception("传入参数错误:replyNote为空");
            }
            WorkflowUser user = toWorkflowUser(getSessionUser());

            if (!userPermissionValidation(insNodeId, user)) {
                throw new Exception("权限不足");
            }


            InsWf insWf = workflowServcie.backFlow(insNodeId, replyNote, user);

            json.setObj(insWf);
            json.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            json.setMsg(e.getMessage());
        }
        return json;
    }


    /**
     * 查询当前用户处理过/未处理的流程任务
     *
     * @param startTime
     * @param endTime
     * @param deadTime
     * @param flowState
     * @param nodeState
     * @param pf
     * @return
     */
    @RequestMapping("/getMyInsFlowNodes")
    @ResponseBody
    public Grid getMyInsFlowNodes(Long insFlowId, String insFlowDesc, String startTime, String endTime, String deadTime, Integer flowState, Integer nodeState, PageFilter pf) {
        Grid grid = new Grid();
        try {
            UserBasic sessionUser = getSessionUser();
//            String roles = StringUtils.join(getRolesByUid(user.getUid()), ",");
            String roles = "";
            List<InsWfNode> insWfNodes = workflowServcie.getInsFlowNodesByPage(insFlowId, insFlowDesc, sessionUser.getPartyId(), 0L, sessionUser.getUid(), sessionUser.getOrgId(), roles, sessionUser.getOrgCode(), startTime, endTime, deadTime, flowState, nodeState, pf);
            if (insWfNodes != null && !insWfNodes.isEmpty()) {
                for (InsWfNode node : insWfNodes) {
                    if (node.getNodeState() == WorkflowConstant.FLOW_STATE_TODO) {
                        StringBuilder sb = new StringBuilder();
                        if (NumberUtils.isNotNullOrZero(node.getUid())) {
                            String excuteName = RedisHelper.getUname(node.getUid());
                            sb.append(excuteName).append(",");
                        }

                        getTodoUserList(sb,node);

                        node.setTodoUsers(sb.toString());
                    }
                }
                long total = workflowServcie.countInsFlowNodes(insFlowId, insFlowDesc, sessionUser.getPartyId(), 0L, sessionUser.getUid(), sessionUser.getOrgId(), roles, sessionUser.getOrgCode(), startTime, endTime, deadTime, flowState, nodeState).longValue();
                grid.setRows(insWfNodes);
                grid.setTotal(total);
            }
        } catch (Exception e) {
            e.printStackTrace();
            grid.setErrorMsg(e.getMessage());
        }
        return grid;
    }

    private void getTodoUserList(StringBuilder sb,InsWfNode node){
        if (NumberUtils.isNotNullOrZero(node.getRoleId()) && NumberUtils.isNotNullOrZero(node.getOrgId())) {
            List<UserBasic> todoUserBasics = userService.getUserBasicsByRole(node.getRoleId(), node.getOrgId(), null);
            for (UserBasic todoUserBasic : todoUserBasics) {
                if (sb.toString().indexOf(todoUserBasic.getUserName()) == -1) {
                    sb.append(todoUserBasic.getUserName()).append(",");
                }
            }
        }
        if (NumberUtils.isNotNullOrZero(node.getRoleId()) && StringUtils.isNotBlank(node.getOrgCode())) {
            List<UserBasic> todoUserBasics = userService.getUserBasicsByRole(node.getRoleId(), null, node.getOrgCode());
            for (UserBasic todoUserBasic : todoUserBasics) {
                if (sb.toString().indexOf(todoUserBasic.getUserName()) == -1) {
                    sb.append(todoUserBasic.getUserName()).append(",");
                }
            }
        }
    }

    /**
     * 查询当前用户创建的流程任务
     *
     * @param startTime
     * @param endTime
     * @param deadTime
     * @param flowState
     * @param nodeState
     * @param pf
     * @return
     */
    @RequestMapping("/getMyCrtInsFlowNodes")
    @ResponseBody
    public Grid getMyCrtInsFlowNodes(Long insFlowId, String insFlowDesc, String startTime, String endTime, String
            deadTime, Integer flowState, Integer nodeState, PageFilter pf) {
        Grid grid = new Grid();
        try {
            UserBasic sessionUser = getSessionUser();

            List<InsWfNode> insWfNodes = workflowServcie.getInsFlowNodesByPage(insFlowId, insFlowDesc, sessionUser.getPartyId(), sessionUser.getUid(), 0L, 0L, null, null, startTime, endTime, deadTime, flowState, nodeState, pf);
            if (insWfNodes != null && !insWfNodes.isEmpty()) {
                for (InsWfNode node : insWfNodes) {
                    if (node.getNodeState() == WorkflowConstant.FLOW_STATE_TODO) {
                        StringBuilder sb = new StringBuilder();
                        if (NumberUtils.isNotNullOrZero(node.getUid())) {
                            String excuteName = RedisHelper.getUname(node.getUid());
                            sb.append(excuteName).append(",");
                        }
                        getTodoUserList(sb,node);
                        node.setTodoUsers(sb.toString());
                    }
                }

                long total = workflowServcie.countInsFlowNodes(insFlowId, insFlowDesc, sessionUser.getPartyId(), sessionUser.getUid(), 0L, 0L, null, null, startTime, endTime, deadTime, flowState, nodeState).longValue();
                grid.setRows(insWfNodes);
                grid.setTotal(total);
            }
        } catch (Exception e) {
            e.printStackTrace();
            grid.setErrorMsg(e.getMessage());
        }
        return grid;
    }

    /**
     * 根据用户编号查询用户处理过/未处理的流程任务
     *
     * @param startTime
     * @param endTime
     * @param deadTime
     * @param flowState
     * @param nodeState
     * @param pf
     * @return
     */
    @RequestMapping("/getInsFlowNodesByUid")
    @ResponseBody
    public Grid getInsFlowNodesByUid(Long insFlowId, String insFlowDesc, Long uid, String startTime, String
            endTime, String deadTime, Integer flowState, Integer nodeState, PageFilter pf) {
        Grid grid = new Grid();
        try {
            UserBasic sessionUser = getSessionUser();
            UserBasic user = null;
            String roles = "";
            if (NumberUtils.isNotNullOrZero(uid)) {
                user = userService.getUserBasicByUid(sessionUser.getPartyId(), uid);
                if (user == null) {
                    throw new Exception("用户不存在或者数据异常");
                }
            }
            List<InsWfNode> insWfNodes = workflowServcie.getInsFlowNodesByPage(insFlowId, insFlowDesc, sessionUser.getPartyId(), 0L, uid, user == null ? 0L : user.getOrgId(), roles, user == null ? null : user.getOrgCode(), startTime, endTime, deadTime, flowState, nodeState, pf);

            if (insWfNodes != null && !insWfNodes.isEmpty()) {
                for (InsWfNode node : insWfNodes) {
                    if (node.getNodeState() == WorkflowConstant.FLOW_STATE_TODO) {
                        StringBuilder sb = new StringBuilder();
                        if (NumberUtils.isNotNullOrZero(node.getUid())) {
                            String excuteName = RedisHelper.getUname(node.getUid());
                            sb.append(excuteName).append(",");
                        }
                        getTodoUserList(sb,node);
                        node.setTodoUsers(sb.toString());
                    }
                }
                long total = workflowServcie.countInsFlowNodes(insFlowId, insFlowDesc, sessionUser.getPartyId(), 0L, uid, user == null ? 0L : user.getOrgId(), roles, user == null ? null : user.getOrgCode(), startTime, endTime, deadTime, flowState, nodeState).longValue();
                grid.setRows(insWfNodes);
                grid.setTotal(total);
            }

        } catch (Exception e) {
            e.printStackTrace();
            grid.setErrorMsg(e.getMessage());
        }
        return grid;
    }

    /**
     * 根据用户编号查询已完成的任务流程
     *
     * @param dealUid
     * @param startTime
     * @param endTime
     * @param pf
     * @return
     */
    @RequestMapping("/getDoneInsFlows")
    @ResponseBody
    public Grid getDoneInsFlows(Long insFlowId, String insFlowDesc, Long dealUid, String startTime, String
            endTime, PageFilter pf) {
        Grid grid = new Grid();
        try {
            UserBasic sessionUser = getSessionUser();
            UserBasic crtUser = null;
            if (NumberUtils.isNotNullOrZero(dealUid)) {
                crtUser = userService.getUserBasicByUid(sessionUser.getPartyId(), dealUid);
                if (crtUser == null) {
                    throw new Exception("创建用户不存在或者数据异常");
                }
            }
            List<InsWf> insFlows = workflowServcie.getInsFlows(insFlowId, insFlowDesc, null, dealUid, startTime, endTime, WorkflowConstant.FLOW_STATE_DONE, null, null, pf);

            if (insFlows != null && !insFlows.isEmpty()) {
                for (InsWf insFlow : insFlows) {
                    String uname = RedisHelper.getUname(insFlow.getCreateUid());
                    insFlow.setUserName(uname);
                }
                long total = workflowServcie.countInsFlows(insFlowId, insFlowDesc, null, dealUid, startTime, endTime, WorkflowConstant.FLOW_STATE_DONE, null, null).longValue();
                grid.setRows(insFlows);
                grid.setTotal(total);
            }

        } catch (Exception e) {
            e.printStackTrace();
            grid.setErrorMsg(e.getMessage());
        }
        return grid;
    }

    /**
     * 根据用户编号查询已完成的任务流程
     *
     * @param dealUid
     * @param startTime
     * @param endTime
     * @param pf
     * @return
     */
    @RequestMapping("/getInsFlows")
    @ResponseBody
    public Grid getInsFlows(Long insFlowId, String insFlowDesc, Long dealUid, String startTime, String
            endTime, Long flowState, PageFilter pf) {
        Grid grid = new Grid();
        try {
            UserBasic sessionUser = getSessionUser();
            UserBasic crtUser = null;
            if (NumberUtils.isNotNullOrZero(dealUid)) {
                crtUser = userService.getUserBasicByUid(sessionUser.getPartyId(), dealUid);
                if (crtUser == null) {
                    throw new Exception("创建用户不存在或者数据异常");
                }
            }
            List<InsWf> insFlows = workflowServcie.getInsFlows(insFlowId, insFlowDesc, null, dealUid, startTime, endTime, flowState, null, sessionUser.getOrgCode(), pf);

            if (insFlows != null && !insFlows.isEmpty()) {
                for (InsWf insFlow : insFlows) {
                    String uname = RedisHelper.getUname(insFlow.getCreateUid());
                    insFlow.setUserName(uname);
                }
                long total = workflowServcie.countInsFlows(insFlowId, insFlowDesc, null, dealUid, startTime, endTime, flowState, null, sessionUser.getOrgCode()).longValue();
                grid.setRows(insFlows);
                grid.setTotal(total);
            }

        } catch (Exception e) {
            e.printStackTrace();
            grid.setErrorMsg(e.getMessage());
        }
        return grid;
    }

    /**
     * 查询当前用户已完成任务流程
     *
     * @param startTime
     * @param endTime
     * @param pf
     * @return
     */
    @RequestMapping("/getMyDoneInsFlows")
    @ResponseBody
    public Grid getMyDoneInsFlows(Long insFlowId, String insFlowDesc, String startTime, String endTime, PageFilter
            pf) {
        Grid grid = new Grid();
        try {
            UserBasic sessionUser = getSessionUser();
            List<InsWf> insFlows = workflowServcie.getInsFlows(insFlowId, insFlowDesc, null, sessionUser.getUid(), startTime, endTime, WorkflowConstant.FLOW_STATE_DONE, null, null, pf);

            if (insFlows != null && !insFlows.isEmpty()) {
                long total = workflowServcie.countInsFlows(insFlowId, insFlowDesc, null, sessionUser.getUid(), startTime, endTime, WorkflowConstant.FLOW_STATE_DONE, null, null).longValue();
                grid.setRows(insFlows);
                grid.setTotal(total);
            }

        } catch (Exception e) {
            e.printStackTrace();
            grid.setErrorMsg(e.getMessage());
        }
        return grid;
    }

    /**
     * 查询当前用户已完成任务流程
     *
     * @param startTime
     * @param endTime
     * @param pf
     * @return
     */
    @RequestMapping("/getMyInsFlows")
    @ResponseBody
    public Grid getMyInsFlows(Long insFlowId, String insFlowDesc, String startTime, String endTime, Long flowState, Long nodeState, PageFilter
            pf) {
        Grid grid = new Grid();
        try {
            UserBasic sessionUser = getSessionUser();
            List<InsWf> insFlows = workflowServcie.getInsFlows(insFlowId, insFlowDesc, null, sessionUser.getUid(), startTime, endTime, flowState, nodeState, sessionUser.getOrgCode(), pf);

            if (insFlows != null && !insFlows.isEmpty()) {
                long total = workflowServcie.countInsFlows(insFlowId, insFlowDesc, null, sessionUser.getUid(), startTime, endTime, flowState, nodeState, sessionUser.getOrgCode()).longValue();
                grid.setRows(insFlows);
                grid.setTotal(total);
            }

        } catch (Exception e) {
            e.printStackTrace();
            grid.setErrorMsg(e.getMessage());
        }
        return grid;
    }

    @RequestMapping("/getInsNodesByInsFlowId")
    @ResponseBody
    public Grid getInsNodesByInsFlowId(long insFlowId) {
        Grid grid = new Grid();
        try {

            List<InsWfNode> insWfNodes = workflowServcie.getInsNodesByInsFlowId(insFlowId);
            if (insWfNodes == null || insWfNodes.isEmpty()) {
                throw new Exception("未找到工作流节点数据");
            } else {
                for (InsWfNode node : insWfNodes) {
                    if (node.getNodeState() == WorkflowConstant.FLOW_STATE_TODO) {
                        StringBuilder sb = new StringBuilder();
                        if (NumberUtils.isNotNullOrZero(node.getUid())) {
                            String excuteName = RedisHelper.getUname(node.getUid());
                            sb.append(excuteName).append(",");
                        }
                        getTodoUserList(sb,node);
                        node.setTodoUsers(sb.toString());
                    }
                }
                grid.setRows(insWfNodes);
            }

            grid.setRows(insWfNodes);
        } catch (Exception e) {
            e.printStackTrace();
            grid.setErrorMsg(e.getMessage());
        }
        return grid;
    }

    protected WorkflowUser toWorkflowUser(UserBasic sessionUser) {
        WorkflowUser user = new WorkflowUser();
        user.setOrgCode(sessionUser.getOrgCode());
        user.setOrgId(sessionUser.getOrgId());
        user.setPartyId(sessionUser.getPartyId());
        user.setUid(sessionUser.getUid());
        return user;
    }

    /**
     * 临时存储
     *
     * @param file
     * @return
     */
    @ResponseBody
    @RequestMapping("/fileUpload")
    public Json fileUpload(@RequestParam("fileupload") MultipartFile file) {
        Json json = new Json();
        try {
            if (file == null) {
                throw new Exception("文件不能为空");
            }

            ResConfig config = resService.getResConfig("Upload");
            if (config == null) {
                throw new Exception("请配置永久存储路径");
            }

            WfTempResource wfTempResource = saveFileToLocal(file);
            wfTempResource.setStoreUrl(config.getAttachUrl() + wfTempResource.getStoreUrl());
            wfTempResource = workflowServcie.saveWfTempResource(wfTempResource, "TempUpload");
            json.setSuccess(true);
            json.setObj(wfTempResource);
            json.setMsg("success");
        } catch (Exception e) {
            json.setMsg(e.getMessage());
        }
        return json;
    }

    /**
     * 转派
     *
     * @param insNodeId
     * @param agentUid
     * @return
     */
    @ResponseBody
    @RequestMapping("/transferDealUser")
    public Json transferDealUser(Long insNodeId, Long agentUid) {
        Json json = new Json();
        try {
            if (insNodeId == null) {
                throw new Exception("insNodeId不能为空");
            }
            if (agentUid == null) {
                throw new Exception("agentUid不能为空");
            }

            UserBasic sessionUser = getSessionUser();

            UserBasic agentUser = userService.getUserBasicByUid(sessionUser.getPartyId(), agentUid);
            if (agentUser == null) {
                throw new Exception("转派用户不存在或者数据异常");
            }

            InsWfNode insWfNode = workflowServcie.getInsWfNodeById(insNodeId);
            if (insWfNode == null) {
                throw new Exception("流程数据未找到");
            }

            if (insWfNode.getPartyId() != agentUser.getPartyId()) {
                throw new Exception("该用户没有权限");
            }

            insWfNode = workflowServcie.transferDealUser(insWfNode, agentUid);
            json.setSuccess(true);
            json.setObj(insWfNode);
            json.setMsg("success");
        } catch (Exception e) {
            json.setMsg(e.getMessage());
        }
        return json;
    }

    private WfTempResource saveFileToLocal(MultipartFile file) {

        WfTempResource resource = null;
        if (!file.isEmpty()) {
            try {
                resource = new WfTempResource();
                String currentDate = DateUtil.getFormattedDate(new Date(), "yyyyMMdd");

                String newFileName = generateUUIDFileName(file.getOriginalFilename());
                String filePath = Configure.getFileTempDir() + "/" + currentDate + "/";
                File fileDir = new File(filePath);
                if (!fileDir.exists()) {
                    fileDir.mkdirs();
                }
                String fileFullName = filePath + System.getProperty("file.separator") + newFileName;
                // 转存文件
                String resType = FileTypeUtil.getFileSuffix(fileFullName);
                file.transferTo(new File(fileFullName));
                resource.setSize(file.getSize());
                resource.setResType(resType);
                resource.setResourceName(newFileName);
                resource.setResourceOriginalName(file.getOriginalFilename());
                resource.setStoreDate(currentDate);
                resource.setStoreSrc("TEMP_LOCAL");
                resource.setStoreUrl(filePath + newFileName);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return resource;
    }

    private String generateUUIDFileName(String fileOriginalName) {
        String fileExtensionName = FileTypeUtil.getExtensionName(fileOriginalName);
        String newFileName = UUID.randomUUID().toString();
        if (StringUtils.isNotBlank(fileExtensionName)) {
            newFileName += "." + fileExtensionName;
        }
        return newFileName;
    }

    protected boolean userPermissionValidation(long insNodeId, WorkflowUser wfWorkflowUser) {
        InsWfNode insWfNode = workflowServcie.getInsWfNodeById(insNodeId);

        if (NumberUtils.isNotNullOrZero(insWfNode.getUid()) && insWfNode.getUid() == wfWorkflowUser.getUid()) {
            return true;
        } else {
            List<SecRole> roles = userService.querySecRoleByUid(wfWorkflowUser.getUid());
            for (SecRole role : roles) {
                if ((role.getRoid() == insWfNode.getRoleId()) && (insWfNode.getOrgId() == wfWorkflowUser.getOrgId())) {
                    return true;
                } else if ((role.getRoid() == insWfNode.getRoleId()) && (insWfNode.getOrgCode().indexOf(wfWorkflowUser.getOrgCode()) != -1)) {
                    return true;
                }
            }
        }
        return false;
    }
}
